﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace Lesson15_UDP服务端_综合练习
{
    internal class Client
    {
        //心跳时间
        private long HeartTime = 0;
        //超时时间
        private int TIME_OUT_SECOND = 5;
        private long CheckTime = 0;
        private IPEndPoint clientIpPoint;

        public IPEndPoint IPEndPoint => clientIpPoint;
        public string ClientId;

        public Client(string ip, int port)
        {
            clientIpPoint = new IPEndPoint(IPAddress.Parse(ip), port);
            ClientId = string.Format("{0}:{1}", clientIpPoint.Address.ToString(), clientIpPoint.Port);
        }

        public bool CheckTimeOut()
        {
            long nowTime = DateTime.Now.Ticks / TimeSpan.TicksPerSecond;
            if (nowTime - HeartTime >= TIME_OUT_SECOND)
                return true;
            return false;
        }

        public void ReceiveMsg(byte[] bytes)
        {
            byte[] cachBytes = new byte[512];
            bytes.CopyTo(cachBytes, 0);

            ThreadPool.QueueUserWorkItem(ReceiveHandle, cachBytes);
        }

        public void ReceiveHandle(object obj)
        {
            try
            {
                byte[] bytes = obj as byte[];
                //区分消息
                int nowIndex = 0;
                int msgID = BitConverter.ToInt32(bytes, 0);
                nowIndex += 4;
                int msgLen = BitConverter.ToInt32(bytes, nowIndex);
                nowIndex += 4;
                BaseMsg baseMsg = null;
                switch (msgID)
                {

                    case 999:
                        {
                            baseMsg = new HeartMsg();
                            break;
                        }
                    case 1001:
                        {
                            baseMsg = new RoleMsg();
                            baseMsg.Reading(bytes, nowIndex);
                            break;
                        }
                    case 1003:
                        {
                            baseMsg = new QuitMsg();
                            break;
                        }
                }
                if (baseMsg != null)
                    MsgHandle(baseMsg);
            }
            catch(Exception e)
            {
                Program.socket.RemoteClient(this.ClientId);
                Console.WriteLine("[ClientSocket][ReceiveHandle] Fail(Id:{0} Error:{1})", ClientId, e.Message);
            }
        }

        public void MsgHandle(BaseMsg msg)
        {
            try
            {
                if (msg is HeartMsg)
                {
                    HeartTime = DateTime.Now.Ticks / TimeSpan.TicksPerSecond;
                    Console.WriteLine("客户端{0}心跳.", ClientId);
                }
                else if (msg is RoleMsg)
                {
                    Console.WriteLine("接收到客户端[{0}]消息:", ClientId);
                    (msg as RoleMsg).Print();
                }
                else if (msg is QuitMsg)
                {
                    Program.socket.RemoteClient(this.ClientId);
                }
            }
            catch (Exception e)
            {
                Program.socket.RemoteClient(this.ClientId);
                Console.WriteLine("[ClientSocket][MsgHandle] Fail(Id:{0} Error:{1})", ClientId, e.Message);
            }
        }
    }

}
